home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Simulation / PDP-8 Simulator / Source Code / PDPLoader.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-13  |  10.6 KB  |  473 lines  |  [TEXT/KAHL]

  1. /*************************************************************************************
  2. *
  3. *        PDP-8 Simulation Program- code loader
  4. *
  5. *        ©1992 Graham Cox. All Rights Reserved.
  6. *
  7. *        Modification History:
  8. *        9/3/92 created from scratch.    
  9. *
  10. *
  11. *
  12. *************************************************************************************/
  13.  
  14. #include    "PDPGlobalEqu.p"
  15. #include     "Global.h"
  16. #include    "EditGlobalEqu.p"
  17.  
  18. #include "PDPLoader.proto.h"
  19.  
  20. PDPMemHdl    GetMemory(WindowPtr theWindow);
  21. ObjectPtr    TranslateBoolToCoxy(oHandle object);
  22. textEdHdl     GetWEditRecord(WindowPtr theWindow);
  23. WindowPtr    GetProcessWindow(int processID);
  24. char        IsEditKind(WindowPtr);
  25.  
  26. int        TargetProcessID =1;        /* global target process ID for assemble command */
  27.  
  28. int LoadProcessMemory(WindowPtr targetProcess,ObjectPtr codeFile)
  29. {
  30.     /* this procedure implements the loader. The file pointed to (previously loaded if on
  31.         disk) is copied into memory at the address specified in the file. The memory is
  32.         the simulated process memory associated with the target window. The function 
  33.         returns an error code to indicate success (0 is no error) */
  34.     
  35.     PDPMemHdl    TargetMem;
  36.     int            cOrigin,cWords,cMaxWords;
  37.     PDPWordPtr    sourceWord,destWord;
  38.         
  39.     if (IsSimulator(targetProcess)) {
  40.         if (codeFile != NIL && codeFile->version ==1) {
  41.             TargetMem = GetMemory(targetProcess);
  42.             
  43.             if (TargetMem != NIL) {
  44.                 
  45.                 /* OK- we're in business. Decode the origin address, etc */
  46.                 
  47.                 cOrigin = codeFile->codeOrigin;
  48.                 cMaxWords = codeFile->cwLength;
  49.                 
  50.                 if (cOrigin + cMaxWords < 4095) {
  51.                     
  52.                     /* code will fit into memory OK, so let's load it */
  53.                     
  54.                     sourceWord = &codeFile->firstWord;
  55.                     HLock((Handle) TargetMem);
  56.                     destWord = (PDPWordPtr) *TargetMem;
  57.                     destWord += cOrigin;
  58.                     
  59.                     for (cWords =0;cWords<cMaxWords;cWords++) {
  60.                         *destWord = *sourceWord;
  61.                         sourceWord++;
  62.                         destWord++;
  63.                     }
  64.                     
  65.                     HUnlock((Handle) TargetMem);
  66.                     return(noErr);
  67.                 }
  68.                 else
  69.                     return(CodeFileTooLong);
  70.             }
  71.             else
  72.                 return(TargetHasNoMemory);
  73.         }
  74.         else
  75.             return(CodeFileBadVersion);
  76.     }
  77.     else
  78.         return(TargetNotSimulator);
  79. }
  80.                     
  81.  
  82. ObjectPtr    MakeDummyCodeFile(void)
  83. {
  84.     /* creates space for a file, sets up the header, and fills it with random data. This
  85.         can then be saved as a dummy file or loaded into a process. */
  86.     
  87.     ObjectPtr    theFile;
  88.     PDPWord        theWord;
  89.     int            wCount;
  90.     PDPWordPtr    destPtr;
  91.     
  92.     theFile = NewPtr(sizeof(ObjectHeader) + (sizeof(PDPWord) * 1000));
  93.     if (theFile != NIL) {
  94.         theFile->version = 1;
  95.         theFile->codeOrigin = 5;
  96.         theFile->cwLength = 1001;
  97.         theFile->reserved = 'test';
  98.         
  99.         destPtr = &theFile->firstWord;
  100.         
  101.         for(wCount =0;wCount<1001;wCount++) {
  102.             *destPtr = Random() & 0x0FFF;
  103.             destPtr++;
  104.         }
  105.     }
  106.     
  107.     return(theFile);
  108. }
  109.  
  110.  
  111. PDPLoad(WindowPtr theWindow,SFReply *theReply)
  112. {
  113.     /* High-Level call to install object code into window process from file */
  114.         
  115.     ObjectPtr    theCode;
  116.     int            theErr,fPath;
  117.     long        fBytes;
  118.     
  119.     if (theReply->good && IsSimulator(theWindow)) {
  120.         if (! FSOpen(&theReply->fName,theReply->vRefNum,&fPath)) {
  121.             if (! GetEOF(fPath,&fBytes)) {
  122.                 
  123.                 theCode = (ObjectPtr) NewPtr(fBytes);
  124.                 if (theCode != NIL) {
  125.                     if (! FSRead(fPath,&fBytes,(Ptr)theCode)) {
  126.             
  127.                         theErr = LoadProcessMemory(theWindow,theCode);
  128.                         if (theErr)
  129.                             ShowProcessError(theErr);
  130.                         MarkForUpdate(theWindow);
  131.                     }
  132.                     DisposPtr(theCode);
  133.                 }
  134.             }
  135.             theErr = FSClose(fPath);
  136.         }
  137.     }
  138. }
  139.  
  140.  
  141. ClearProcessMem(WindowPtr theWindow)
  142. {
  143.     /* sets all locations in simulated memory to zero */
  144.     
  145.     PDPMemHdl    theMemory;
  146.     PDPMemPtr    mPtr;
  147.     PDPWord        index;
  148.     
  149.     if (IsSimulator(theWindow)) {
  150.         theMemory = GetMemory(theWindow);
  151.         
  152.         if (theMemory != NIL) {
  153.             HLock((Handle) theMemory);
  154.             for (index = 0; index <4096;index++) {
  155.                 mPtr = *theMemory;
  156.                 mPtr[index] = 0;
  157.             }
  158.             HUnlock((Handle) theMemory);
  159.         }
  160.     }
  161. }
  162.  
  163.  
  164. ChooseTextFile(SFReply *theReply)
  165. {
  166.     /* presents SF Open dialog box for text files */
  167.     
  168.     SFTypeList            theList;
  169.     Point                where;
  170.     
  171.     theList[0] = 'TEXT';
  172.     SetPt(&where,100,100);
  173.     SFDialogLocation(getDlgID,&where);
  174.     SFGetFile(where,(ConstStr255Param)'/p',NIL,2,&theList,NIL,theReply);
  175. }
  176.  
  177.  
  178. #define    ProgressDialogID    515
  179.  
  180.  
  181. PDPAssembleCode(WindowPtr theWindow)
  182. {
  183.     /* incredibly high level call to implement the assemble command */
  184.     
  185.     extern    int        AssemblyDest;
  186.     SFReply            tFile;
  187.     pHandle            theProgram;
  188.     oHandle            theObject;
  189.     ObjectPtr        coxyFormat;
  190.     int                theErr;
  191.     StringHandle    saveFName;
  192.     DialogPtr        progressBox;
  193.     Rect            dRect;
  194.     long            dWait,lineNum;
  195.     textEdHdl        asmText;
  196.     
  197.     if (IsEditKind(theWindow)) {
  198.         asmText = GetWEditRecord(theWindow);
  199.         if (asmText != NIL)
  200.             tFile = (*asmText)->asmFile;
  201.         else
  202.             ChooseTextFile(&tFile);
  203.         if (tFile.good) {
  204.             AsmError = noErr;
  205.             SetHiliteLine(theWindow,NIL);
  206.             
  207.             progressBox = GetNewDialog(ProgressDialogID,NIL,(WindowPtr)-1L);
  208.             
  209.             if (progressBox != NIL) {
  210.             
  211.                 theProgram = newProgram();
  212.                 
  213.                 if (theProgram != NIL) {
  214.                     ParamText("\p",&tFile.fName,"\p1","\p");
  215.                     dRect = progressBox->portRect;
  216.                     MoveWindow(progressBox,hCentre(&dRect),GetMBarHeight()+10,TRUE);
  217.                     ShowWindow(progressBox);
  218.                     DrawDialog(progressBox);
  219.                     
  220.                     (*(*theProgram)->sourceCode)->fileSpec = tFile;
  221.                     
  222.                     loadSource((*theProgram)->sourceCode);
  223.                     if (!AsmError) {
  224.                     
  225.                         pass(theProgram,1);
  226.                         
  227.                         if (! AsmError) {
  228.                             
  229.                             createObjectSpace((*theProgram)->objectCode);
  230.                             
  231.                             if (!AsmError) {
  232.                                 Delay(40,&dWait);
  233.                                 ParamText("\p",&tFile.fName,"\p2","\p");
  234.                                 DrawDialog(progressBox);
  235.                                 
  236.                                 pass(theProgram,2);
  237.                                 Delay(60,&dWait);
  238.                                 
  239.                                 if (!AsmError) {
  240.                                     coxyFormat = TranslateBoolToCoxy((*theProgram)->objectCode);
  241.                                 }
  242.                             }
  243.                         }
  244.                     }
  245.                      DisposDialog(progressBox);
  246.                      lineNum = (*(*theProgram)->sourceCode)->line;
  247.                      disposeProgram(theProgram);
  248.     
  249.                     if (AsmError) {
  250.                         AssemblyError(AsmError,lineNum);
  251.                         SetHiliteLine(theWindow,lineNum);
  252.                     }
  253.                     else {    
  254.                         AssemblyError(CompletedOK,-1L);
  255.                         
  256.                      
  257.                         if (AssemblyDest == toMemory) {
  258.                             theErr = LoadProcessMemory(GetProcessWindow(TargetProcessID),coxyFormat);
  259.                             if (theErr)
  260.                                 AssemblyError(theErr,-1L);
  261.                             else
  262.                                 MarkForUpdate(GetProcessWindow(TargetProcessID));
  263.                         }
  264.                         else {
  265.                             saveFName = NewString(&tFile.fName);
  266.                             if (saveFName != NIL) {
  267.                                 MakeSaveName(saveFName);
  268.                                 NameObjectFile(saveFName,&tFile);
  269.                                 DisposHandle(saveFName);
  270.                                 SaveObjectFile(&tFile,coxyFormat);
  271.                             }
  272.                         }
  273.                         DisposPtr(coxyFormat);
  274.                     }
  275.                     MarkForUpdate(theWindow);
  276.                 }
  277.                 else
  278.                     AssemblyError(NotEnoughMemory,-1L);
  279.             }
  280.         }
  281.     }
  282. }
  283.  
  284.  
  285. ObjectPtr    TranslateBoolToCoxy(oHandle object)
  286. {
  287.     /* translates Adrians block of object stuff to my type, complete with header! WOW! */
  288.     
  289.     ObjectPtr    temp;
  290.     long        size;
  291.     Ptr            s1,s2;
  292.     
  293.     size = (*object)->size;
  294.     temp = (ObjectPtr) NewPtr(sizeof(ObjectHeader) + size * sizeof(wordType));
  295.     if (temp != NIL) {
  296.         temp->version = 1;
  297.         temp->codeOrigin = (*object)->startAddress;
  298.         temp->cwLength = size;
  299.         temp->reserved = 0;
  300.         
  301.         HLock((Handle) (*object)->storage);
  302.         s1 = *(*object)->storage;
  303.         s2 = &temp->firstWord;
  304.         
  305.         BlockMove(s1,s2,size * sizeof(wordType));
  306.         HUnlock((Handle) (*object)->storage);
  307.     }
  308.     
  309.     return(temp);
  310. }
  311.  
  312. #define    ErrorStringsID        129
  313.  
  314. AssemblyError(int    errorCode,long lineNum)
  315. {
  316.     /* put up alert box with error message reporting assembly errors. If lineNum = -1
  317.         the line number message is not included */
  318.         
  319.     int        aHit;
  320.     Str32    lineStr,valStr;
  321.     Str255    message;
  322.     
  323.     if (errorCode) {
  324.         if (lineNum >= 0)
  325.             GetIndString(&lineStr,standardResID,11);
  326.         else
  327.             CopyString("\p",&lineStr);
  328.         NumToString(lineNum,&valStr);
  329.         GetIndString(&message,ErrorStringsID,-errorCode-176);
  330.         ParamText(&message,&lineStr,&valStr,"\p");
  331.         aHit = xAlert(129,NIL);
  332.     }
  333. }
  334.             
  335.  
  336. MakeSaveName(StringHandle theString)
  337. {
  338.     /* makes a suitable name for saving the object file as. This is the same as the
  339.         source file, less any .extension, appended with .OBJ */
  340.     
  341.     Ptr        s1,s2;
  342.     long    L1,L2,mResult;    
  343.     Str32    targ,replace;
  344.     
  345.     CopyString("\p.OBJ",&replace);
  346.     CopyString("\p.SRC",&targ);
  347.     s1 = &targ[1];
  348.     s2 = &replace[1];
  349.     
  350.     mResult = Munger(theString,1,s1,4,s2,4);
  351.     if (mResult < 0) {
  352.         /* we failed to find .SRC, so just append the extension */
  353.         L1 = **theString;
  354.         mResult = Munger(theString,L1+1,NIL,0,s2,4);
  355.         **theString = L1+4;
  356.     }
  357. }        
  358.         
  359.  
  360. NameObjectFile(StringHandle    defaultName,SFReply *theReply)
  361. {
  362.     /* presents SF Save dialog Box for saving object file */
  363.     
  364.     Point                where;
  365.     
  366.     SetPt(&where,100,100);
  367.     SFDialogLocation(putDlgID,&where);
  368.     HLock((Handle) defaultName);
  369.     SFPutFile(where,NIL,*defaultName,NIL,theReply);
  370.     HUnlock((Handle) defaultName);
  371. }
  372.  
  373.  
  374. SaveObjectFile(SFReply *fSpec,ObjectPtr theCode)
  375. {
  376.     /* writes out the object file to the disk if you're lucky */
  377.     
  378.     OSErr        theErr;
  379.     int            pathRef;
  380.     long        bytes;
  381.     
  382.     if (fSpec->good) {
  383.         theErr = Create(&fSpec->fName,fSpec->vRefNum,'PDP8','OBJF');
  384.         if (theErr == noErr || theErr == dupFNErr) {
  385.             if (! FSOpen(&fSpec->fName,fSpec->vRefNum,&pathRef)) {
  386.                 bytes = GetPtrSize(theCode);
  387.                 
  388.                 theErr = FSWrite(pathRef,&bytes,theCode);
  389.                 
  390.                 if (theErr)
  391.                     SysBeep(1);
  392.                     
  393.                 theErr = FSClose(pathRef);
  394.             }
  395.         }
  396.     }
  397. }
  398.  
  399.  
  400. #define        SetTargetDialogID     516
  401. #define        STItemEdit            3
  402.  
  403.  
  404. int        SetTargetProcess(long currentProcess)
  405. {
  406.     /* displays dialog box to set the target process ID */
  407.     
  408.     DialogPtr    theDialog;
  409.     int            theItem,itemType;
  410.     Handle        itemHand;
  411.     Rect        itemBox;
  412.     Str32        edStr;
  413.     long        tempProcID;
  414.     
  415.     theDialog = GetNewDialog(SetTargetDialogID,NIL,(WindowPtr)-1L);
  416.     if (theDialog != NIL) {
  417.         PosDialog(theDialog);
  418.         OutlineDItem(theDialog,ok);
  419.  
  420.         GetDItem(theDialog,STItemEdit,&itemType,&itemHand,&itemBox);
  421.         NumToString(currentProcess,&edStr);
  422.         SetIText(itemHand,&edStr);
  423.         SelIText(theDialog,STItemEdit,0,32767);
  424.         theItem = 0;
  425.         while (theItem == 0) {
  426.             ModalDialog(NIL,&theItem);
  427.             switch (theItem) {
  428.                 case ok:
  429.                     GetDItem(theDialog,STItemEdit,&itemType,&itemHand,&itemBox);
  430.                     GetIText(itemHand,&edStr);
  431.                     StringToNum(&edStr,&tempProcID);
  432.                     if (tempProcID <= 0) {
  433.                         theItem = 0;
  434.                         SysBeep(1);
  435.                         SelIText(theDialog,STItemEdit,0,32767);
  436.                         break;
  437.                     }
  438.                     else
  439.                         currentProcess = tempProcID;
  440.                 case cancel:
  441.                     break;
  442.                 default:
  443.                     theItem = 0;
  444.                     break;
  445.             }
  446.         }
  447.         DisposDialog(theDialog);
  448.         return(LoWord(currentProcess));
  449.     }
  450. }
  451.  
  452.  
  453. WindowPtr GetProcessWindow(int processID)
  454. {
  455.     /* searches for a process window with the given ID. If available, returns the window,
  456.         otherwise returns NIL. processID can't be zero, or an invalid window is returned */
  457.     
  458.     WindowPeek    temp;
  459.     int            wProcess;
  460.     
  461.     temp = FrontWindow();
  462.     while (temp != NIL) {
  463.         wProcess = GetProcessID(temp);
  464.         if (wProcess == processID)
  465.             break;
  466.         else
  467.             temp = temp->nextWindow;
  468.     }    
  469.     return(temp);    
  470. }
  471.  
  472.  
  473.